package wsi.input.degree;

import java.io.File;

import org.json.JSONArray;
import org.rygh.core.file.FileIterator;
import org.rygh.semantic.gui.swing.input.Input;
import org.rygh.semantic.model.rdf.Entity;
import org.rygh.semantic.sparql.RecursiveSparQL;
import org.rygh.semantic.sparql.SparQL;

import wsi.function.DirManager;
import wsi.input.InputFileTuple;

public class SimpleDegreeSelector extends DegreeSelector {

	public SimpleDegreeSelector(DirManager dir) {
		super(dir);

		if (function.isDirect()) {
			type = function.getRuntimeInfo().getType();

			if (type == null) {
				log.info("[warn] missing input type for "
						+ function.getFullName());
				return;
			}
		}
	}

	@Override
	protected void compute() {
		if (type == null)
			return;

		if (offline)
			computeOffline();
		else
			computeOnline();

	}

	private void computeOffline() {
		File file = getFile(true);

		if (file == null) {
			System.out.println("[error] cannot fine input file.");
			return;
		} else {
			System.out.printf("degree offline file %s\n", file.getName());
		}

		// final int limit = SampleWorker.__DEGREE_LIMIT;

		/*
		 * we start from the entity less than or equal to limit until we
		 * obtained enough input or the list is exhausted.
		 */

		FileIterator iter = new FileIterator(file);

		iter.begin();

		InputFileTuple tuple;
		Input input;
		Entity entity;
		String s;

		while (!detector.isEnough() && (s = iter.next()) != null) {
			tuple = new InputFileTuple(new JSONArray(s));

			int degree = tuple.getDegree();

			// lift such restriction
			// if (degree > limit)
			// continue;

			entity = tuple.getEntity();

			entity.setDegree(degree);
			input = new Input(entity, namePredicate, tuple.getValue());

			detect(input);
		}

		iter.end();
	}

	private void computeOnline() {
		if (!isYago) {
			SparQL query = new SparQL();
			query.addFact(getTypeFact(type));
			query.addFacts(getNamePredicateFacts());

			computeOnline(query);
		} else {
			RecursiveSparQL query = new RecursiveSparQL();
			query.addFact(getTypeFact(type));
			query.addFacts(getNamePredicateFacts());

			for (int i = 0; i < TYPE_RECURSIVE_HOP && !detector.isEnough(); i++) {
				query.setLevel(i);

				System.out.println("recur query " + i);

				computeOnline(query);
			}
		}

	}
}
